'''
1、封装
// 封装就是隐藏内部实现的细节，只保留功能接口
2、继承
//继承指的是一个对象直接使用另一个对象的属性和方法。
//对一类事物的公共特征进行抽取，形成一个类，这个类就可以被多个对象所使用。
    1.使用一个公共的类来定义这一类事物的公共特征【属性和函数】
    2.具体的每一类事物，都不用写这些公共特征成员了，只要继承即可
    3.在继承的体系里面，一般会称呼公共类为：父类，来继承的类为：子类
    4.子类除了能直接使用原有的功能外，还可以对其进行扩展升级
继承的语法：
    class 子类名(父类名):
        pass
继承可以继承所有但是不能继承私有成员和私有方法 

'''
#父类
class Person:
    def __init__(self, name, age):
        self.name = name  # 公有成员
        self.age = age  # 私有成员
    def eat(self):  # 公有方法
        print('父类eat')
    def sleep(self):  # 私有方法
        print('父类sleep')
    def smoke(self):  # 公有方法
        print('父类smoke')
        
#子类
class Student(Person):  # 子类继承父类的属性和方法,0
    def __init__(self, name, age):  # 重写父类的构造函数
        #万一在第一行就去初始化了子类的属性，但是父类还没有构造出来就先走了子类的一些初始化，这不符合生活常识！
        super().__init__(name, age)  # 调用父类的构造函数,必须放在子类的构造函数的第一行
    def smoke(self):  # 重写父类的方法
        print('子类smoking...')
#创父类对象
p1 = Person('张三', 18)
print(p1.name,p1.age)  # 张三 18
p1.eat()  # eat
p1.sleep()  # AttributeError: 'Person' object has no attribute '__sleep'
p1.smoke()  # smoke
#创子类对象
s1 = Student('李四', 20)
print(s1.name,s1.age)  # 李四 20
s1.eat()  # eat
s1.sleep()  #sleep
s1.smoke()  # smoking...

'''
多继承
class 子类名(父类1,父类2,父类3,...):
    pass
'''


'''
3、多态
//多态指的是同一个对象可以具有多种形态，即同一个对象可以被不同的类所使用。
    多态的实现方式：继承，子类继承父类，子类可以重写父类的方法，从而实现多态
    多态的优点：
        1.可以让代码更加灵活更加通用
        2.多态可以让代码更加简洁，更加易于维护
'''
#父类
class animal:
    def eat(self):  # 公有方法
        print('animal eat')
    def sleep(self):  # 私有方法
        print('animal sleep')
    def smoke(self):  # 公有方法
        print('animal smoke')
#子类
class dog(animal):  # 子类继承父类的属性和方法,0
    def eat(self):  # 重写父类的方法
        print('dog eat')
    def sleep(self):  # 重写父类的方法
        print('dog sleep')
    def smoke(self):  # 重写父类的方法
        print('dog smoke')
#子类
class cat(animal):  # 子类继承父类的属性和方法,0
    def eat(self):  # 重写父类的方法
        print('cat eat')
    def sleep(self):  # 重写父类的方法
        print('cat sleep')
    def smoke(self):  # 重写父类的方法
        print('cat smoke')
class duck(animal):
    pass
#创父类对象
a1 = animal()#父类的对象可以调用父类的方法和属性，但是不能调用子类的方法和属性
a1.eat()  # animal eat
a1.sleep()  # animal sleep
a1.smoke()  # animal smoke
#创子类对象
d1 = dog()#子类的对象继承父类，子类乐意重写父类的方法，从而实现多态
d1.eat()  # dog eat
d1.sleep()  # dog sleep
d1.smoke()  # dog smoke
c1 = cat()
c1.eat()  # cat eat
c1.sleep()  # cat sleep
c2 = duck()
c2.eat()  # animal eat
c2.sleep()  # animal sleep
c2.smoke()  # animal smoke